#include "uart_config.h"

void NUC_USART_Init(uint8_t *rx1_buf, uint8_t *rx2_buf, uint16_t rx_buf_num, uint8_t *tx_buf, uint16_t tx_buf_num)
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA| RCC_AHB1Periph_DMA2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
	
    {
        GPIO_InitTypeDef   GPIO_InitStructure;
        USART_InitTypeDef  USART_InitStructure;
			
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
			
				GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
        GPIO_Init(GPIOB, &GPIO_InitStructure);			
				/**USART1 GPIO Configuration    
					PB7     ------> USART1_RX
					PA9     ------> USART1_TX 
				*/
        USART_DeInit(USART1);

        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_Init(USART1, &USART_InitStructure);

        USART_DMACmd(USART1, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);

        USART_ClearFlag(USART1, USART_FLAG_IDLE);
        USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);

        USART_Cmd(USART1, ENABLE);
    }

    {
        NVIC_InitTypeDef   NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NUC_NVIC;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }

    {
        DMA_InitTypeDef  DMA_InitStructure;
		    DMA_DeInit(DMA2_Stream2);//USART1_rx
		    DMA_DeInit(DMA2_Stream7);//USART1_tx
			
        DMA_InitStructure.DMA_Channel = DMA_Channel_4;
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (USART1->DR);
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rx1_buf;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
        DMA_InitStructure.DMA_BufferSize = rx_buf_num;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
        DMA_Init(DMA2_Stream2, &DMA_InitStructure);

        DMA_DoubleBufferModeConfig(DMA2_Stream2, (uint32_t)rx2_buf, DMA_Memory_0);
        DMA_DoubleBufferModeCmd(DMA2_Stream2, ENABLE);
		
        DMA_InitStructure.DMA_Channel = DMA_Channel_4;
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (USART1->DR);
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)tx_buf;
				DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
				DMA_InitStructure.DMA_BufferSize = tx_buf_num;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
				DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
				DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
				DMA_Init(DMA2_Stream7, &DMA_InitStructure);
		
				DMA_Cmd(DMA2_Stream2, DISABLE); //Add a disable
        DMA_Cmd(DMA2_Stream2, ENABLE);
				
				DMA_Cmd(DMA2_Stream7, DISABLE); //Add a disable
        DMA_Cmd(DMA2_Stream7, ENABLE);
    }
}



void NUC_USART_unable(void)
{
    USART_Cmd(USART1, DISABLE);
}



void NUC_USART_restart(uint16_t dma_buf_num)
{
    USART_Cmd(USART1, DISABLE);
	
    DMA_Cmd(DMA2_Stream2, DISABLE);

    DMA_SetCurrDataCounter(DMA2_Stream2, dma_buf_num);

    USART_ClearFlag(USART1, USART_FLAG_IDLE);
	
	  DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2);
	
    DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF2);

    DMA_Cmd(DMA2_Stream2, ENABLE);
	
    USART_Cmd(USART1, ENABLE);
}



//开启一次DMA传输
//ndtr:数据传输量  
void NUC_DMA_TX(u16 tx_buf_num)
{
	if( DMA_GetFlagStatus(DMA2_Stream7,DMA_FLAG_TCIF7)!=0)
	{
		DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7);

		DMA_Cmd(DMA2_Stream7, DISABLE);                     //关闭DMA传输 

		while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE){}	//确保DMA可以被设置  

		DMA_SetCurrDataCounter(DMA2_Stream7,tx_buf_num);    //数据传输量  

		DMA_Cmd(DMA2_Stream7, ENABLE);                      //开启DMA传输 
	}
}	 


